const fs = require("fs");
const ini = require("ini");
const Sequelize = require("sequelize");
const { QueryTypes } = require("sequelize");
const userName = process.env.username;

let xiamiConfigDatabase = `C:\\Users\\${userName}\\AppData\\Roaming\\Xiami\\xiami_info.ini`;
let xiamiDatabase = `C:\\Users\\${userName}\\AppData\\Roaming\\Xiami\\Xiami.db`;

let cloudMusicDatabase =
  process.platform == "win32"
    ? `C:\\Users\\${userName}\\AppData\\Local\\Netease\\CloudMusic\\Library\\webdb.dat`
    : "/Users/fun/Library/Containers/com.netease.163music/Data/Documents/storage/sqlite_storage.sqlite3";

console.log("cloudMusicDatabase", cloudMusicDatabase);

function getXiamiCollectIds() {
  const configStr = fs.readFileSync(xiamiConfigDatabase, "utf-8");
  const config = ini.parse(configStr);
  const userId = config.xiami.USER_ID;
  const mapping = config.xiami[userId];
  const key = `${userId} = ${mapping};`;
  const lines = configStr.split("\n").filter((_) => _.indexOf(key) > -1);
  if (lines.length) {
    const songIds = lines[0].replace(key, "").split(",");
    return songIds;
  }
  return [];
}

async function loadXiami() {
  const sequelize = new Sequelize("main", null, null, {
    dialect: "sqlite",
    logging: false,
    storage: xiamiDatabase,
  });
  await sequelize.authenticate();
  console.log("Connection has been established successfully.");
  const songIds = getXiamiCollectIds();
  console.log("found song", songIds.length);
  const songRows = await sequelize.query(
    "select * from song_info where song_id in (" + songIds.join(",") + ")",
    { type: QueryTypes.SELECT }
  );

  const formattedSongs = songRows.map((_) => {
    return {
      type: "xiami",
      song_id: _.song_id,
      song_name: _.song_name,
      album_name: _.album_name,
      artist_name: _.artist_name,
      album_logo: _.album_logo,
    };
  });
  //   console.log("songRows", songRows.length);
  //   console.log(formattedSongs);
  return formattedSongs;
}

async function loadCloud() {
  const sequelize = new Sequelize("main", null, null, {
    dialect: "sqlite",
    logging: false,
    storage: cloudMusicDatabase,
  });
  
  await sequelize.authenticate();
  const allPlaylist = await sequelize.query("select * from web_playlist", {
    type: QueryTypes.SELECT,
  });

  const likePlaylist = allPlaylist
    .map((_) => {
      return JSON.parse(_.playlist);
    })
    .filter((playlist) => {
      // const playlist = JSON.parse(_.playlist);
      return playlist.name == "我喜欢的音乐";
    })[0];

  console.log("found", likePlaylist);

  const allIds = await sequelize.query(
    "select * from web_playlist_track where pid = " + likePlaylist.id + ' order by order asc',
    {
      type: QueryTypes.SELECT,
    }
  );

  console.log("list one", allIds[0]);

  let songRows = await sequelize.query(
    "select * from web_track where tid in (" +
      allIds.map((_) => _.tid).join(",") +
      ")",
    {
      type: QueryTypes.SELECT,
    }
  );
  songRows = songRows.map((_) => {
    _.track = JSON.parse(_.track);
    return _;
  });

  console.log("track.sample", songRows[0]);
  const formattedSongs = songRows.map((_) => {
    const track = _.track;
    return {
      type: "cloudmusic",
      song_id: track.id,
      song_name: track.name,
      album_name: track.album.name,
      artist_name: track.artists.map((_) => _.name).join(","),
      album_logo: track.album.picUrl,
    };
  });
  console.log("songRows", formattedSongs.length);
  return formattedSongs;
}

// loadXiami();
loadCloud();
return;

const mergedDatabse = "./all2.db";
const sequelize = new Sequelize("main", null, null, {
  dialect: "sqlite",
  storage: mergedDatabse,
  logging: false,
});

// song_id: track.id,
// song_name: track.name,
// album_name: track.album.name,
// artist_name: track.artists.map((_) => _.name).join(","),
// album_logo: track.album.picUrl,
const Song = sequelize.define(
  "song",
  {
    id: {
      type: Sequelize.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true,
      _autoGenerated: true,
    },
    // userId: Sequelize.INTEGER,
    song_id: Sequelize.INTEGER,
    song_name: Sequelize.STRING,
    type: Sequelize.STRING,
    album_name: Sequelize.STRING,
    artist_name: Sequelize.STRING,
    album_logo: Sequelize.STRING,
  },
  {
    indexes: [
      {
        unique: true,
        fields: ["song_id", "type"],
      },
    ],
  }
);

const UniqueSong = sequelize.define(
  "unique_song",
  {
    id: {
      type: Sequelize.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true,
      _autoGenerated: true,
    },
    // userId: Sequelize.INTEGER,
    song_id: Sequelize.INTEGER,
    song_name: Sequelize.STRING,
    type: Sequelize.STRING,
    album_name: Sequelize.STRING,
    artist_name: Sequelize.STRING,
    album_logo: Sequelize.STRING,
  },
  {
    indexes: [
      {
        unique: true,
        fields: ["song_id", "type"],
      },
    ],
  }
);

const chunk = (arr, size) =>
  Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
    arr.slice(i * size, i * size + size)
  );

(async () => {
  await sequelize.authenticate();
  await Song.sync({ alter: true });
  let allSongs = [];
  const xiamiSongs = await loadXiami();
  const cloudSongs = await loadCloud();
  allSongs = allSongs.concat(xiamiSongs, cloudSongs);
  console.log("found", allSongs.length);
  const stepItems = chunk(allSongs, 100);
  for (let index = 0; index < stepItems.length; index++) {
    const songs = stepItems[index];
    console.log("insert", songs.length);
    try {
      await Song.bulkCreate(songs, { ignoreDuplicates: true });
    } catch (e) {
      console.log(e);
    }
  }
})();

// console.log("process.env.user
